<template>
  <a-form
    ref="formRef"
    :model="formData"
    :rules="formRules"
    label-position="top"
    class="source-site"
    scroll-to-first-error>
    <a-form-item
      v-if="isWeight"
      :rules="priorityRules"
      hide-label
      class="!w-[208px]"
      field="priority">
      <a-input-number
        v-model="formData.priority"
        hide-button
        :precision="0"
        :min="1"
        :max="100"
        placeholder="请输入权重"
        class="!w-full"></a-input-number>
    </a-form-item>
    <a-form-item field="host" hide-label class="!min-w-294px flex-1">
      <a-input
        v-model="formData.host"
        class="!w-full"
        :class="{ '!w-414px': !isWeight }"
        placeholder="请输入域名/IP"></a-input>
    </a-form-item>
    <a-form-item field="port" hide-label class="!min-w-294px flex-1">
      <a-input-number
        v-model="formData.port"
        hide-button
        :precision="0"
        :max="65535"
        class="!w-full"
        :class="{ '!w-414px': !isWeight }"
        placeholder="1~65535"></a-input-number>
    </a-form-item>
    <a-link
      status="danger"
      type="text"
      class="!p-0 !bg-transparent whitespace-nowrap"
      :disabled="disableDelete"
      @click="emit('delete')">
      删除
    </a-link>
  </a-form>
</template>

<script setup lang="ts">
import { A_PRIORITY_TYPE } from '@/constants/site'
import type { Ref } from 'vue'
import type { ISourceSite } from './types'

interface IEmit {
  (event: 'update:algorithm', value: string): void
  (event: 'update:host', value: string): void
  (event: 'update:port', value: number | null): void
  (event: 'priority-change'): void
  (event: 'host-change'): void
  (event: 'delete'): void
  (event: 'add'): void
}

interface IProps {
  priority: number
  host: string
  port: number | null
  disableDelete?: boolean
  primary?: boolean
}

const emit = defineEmits<IEmit>()
const props = withDefaults(defineProps<IProps>(), {
  disableDelete: false,
  primary: false
})

const sourceList = inject('sourceList') as Ref<ISourceSite[]>
const priorityType = inject('priorityType') as Ref<A_PRIORITY_TYPE>
const isWeight = computed(() => priorityType.value === A_PRIORITY_TYPE.WEIGHT)
const formRef = ref()
const formData = reactive({
  priority: useVModel(props, 'priority', emit),
  host: useVModel(props, 'host', emit),
  port: useVModel(props, 'port', emit)
})

const formRules = computed<{ [key: string]: any[] }>(() => {
  return {
    host: [
      { required: true, message: '请输入域名/IP' },
      {
        validator: (value: any, callback: any) => {
          if (!value) {
            callback('请输入域名/IP')
          } else if (
            regexpMap.domain.test(value) ||
            regexpMap.ipv4.test(value)
          ) {
            callback()
          } else {
            callback('请输入正确的域名/IP')
          }
        }
      },
      {
        validator(value: any, callback: any) {
          // 验证源站重复
          const filters = sourceList.value.filter((item) => item.ip === value)
          if (filters.length > 1) {
            callback('源站IP重复')
            return
          }
          callback()
        }
      }
    ],
    port: [
      { required: true, message: '请输入端口号' },
      { validator: validateSitePort }
    ]
  }
})
const priorityRules = computed<any[]>(() => {
  const rules: any[] = [
    { required: true, message: '请输入权重' },
    { type: 'number', min: 1, max: 100, message: '范围1～100' }
  ]
  return rules
})

watch(
  () => formData.priority,
  () => {
    emit('priority-change')
  }
)

watch(
  () => formData.host,
  () => {
    emit('host-change')
  }
)

async function validate(fields?: string[]) {
  if (fields) {
    return await formRef.value?.validateField(fields)
  }
  return await formRef.value?.validate()
}

defineExpose({
  validate
})
</script>

<style scoped lang="less">
.source-site {
  @apply px-4 py-2 !flex flex-row gap-x-8;
  border-top: 1px solid #f1f2f3;
  .arco-form-item {
    @apply w-fit mb-0;
  }
}
</style>
